import { Inject, Injectable } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { User } from './entities/user.entity';
import { Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import * as bcrypt from 'bcrypt';
import { LoginUserDto } from './dto/login-user.dto';
import { JwtService } from '@nestjs/jwt';
import { CryptoService } from 'src/rsa/rsa.service';

@Injectable()
export class UsersService {

  @InjectRepository(User)
  private readonly userRepository: Repository<User>;

  @Inject(CryptoService)
  private cryptoService: CryptoService

  constructor(private jwtService: JwtService) { }

  async create(createUserDto: CreateUserDto) {
    const { username, password, email } = createUserDto;

    // 检查用户名是否已存在
    const existingUsername = await this.userRepository.findOne({ where: { username } });
    const existingUserEmail = await this.userRepository.findOne({ where: { email } });
    if (existingUsername || existingUserEmail) {
      throw new Error('用户名已存在');
    }

    // 创建新用户实例
    const newUser = new User();
    newUser.username = username;
    newUser.name = username;
    // 使用bcrypt对密码进行加密
    newUser.password = await bcrypt.hash(password, 10);
    newUser.email = email;
    const user = this.userRepository.create(newUser);
    // 保存用户到数据库
    return await this.userRepository.save(user);
  }

  async login(loginUserDto: LoginUserDto) {
    let { email, password: dtoPass } = loginUserDto;
    dtoPass = this.cryptoService.decrypt(dtoPass)
    console.log(dtoPass)
    // 查找用户是否存在
    const user = await this.userRepository.findOne({ where: { email } });
    if (!user) {
      throw new Error('用户不存在');
    }
    // 验证密码
    const isPasswordValid = await bcrypt.compare(dtoPass, user.password);
    if (!isPasswordValid) {
      throw new Error('密码错误');
    }

    // 生成JWT token
    const payload = { sub: user.id, username: user.username };
    const token = await this.jwtService.signAsync(payload);
    const { password, ...openUser } = user
    return {
      token,
      user: openUser
    };
  }

  findAll() {
    const users = this.userRepository.find();
    return users;
  }

  async findOne(id: number) {
    return await this.userRepository.findOne({
      where: { id },
      select: ['id', 'username', 'email']
    });
  }

  update(id: number, updateUserDto: UpdateUserDto) {
    return `This action updates a #${id} user`;
  }

  remove(id: number) {
    return `This action removes a #${id} user`;
  }
}
